<?php

namespace app\recode\controller;

use app\aliyun\controller\AliyunFilterWord;
use app\astro\controller\Index as AstroIndex;
use app\check\controller\Check;
use app\common\cachemodel\AppSynastryResult;
use app\common\cachemodel\chat\HzChatLastSendTimeRecord;
use app\common\cachemodel\chat\HzChatRecord;
use app\common\cachemodel\chat\HzChatRecordDetails;
use app\common\cachemodel\FortuneCache;
use app\common\cachemodel\Recode as RecodeCacheModel;
use app\common\controller\Avatar;
use app\common\lib\astrolog\Astrolog;
use app\common\lib\PushQueue;
use app\common\lib\SensorsData;
use app\common\lib\Util;
use app\common\model\User;
use Exception;
use think\Cache;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;
use think\exception\PDOException;
use think\Log;
use think\response\Json;

// 星盘档案管理控制器
class Index extends Check
{
    protected $setting = [
        'natal' => [
            'planet' => [
                [1, 8.5], [1, 7.5], [1, 3.5], [1, 3.5], [1, 4], [1, 4.5], [1, 4.5], [1, 2.5], [1, 2.5], [1, 2.5],
                [0, 0], [0, 0], [0, 0], [0, 0], [1, 2.5], [0, 0], [0, 0], [1, 2.5], [1, 2.5], [1, 2.5], [1, 2.5],
            ],
            'phase' => [
                0 => [1, 0], 60 => [1, 0], 90 => [1, 0], 120 => [1, 0], 180 => [1, 0],
                45 => [0, 0], 135 => [0, 0], 30 => [0, 0], 150 => [0, 0], 72 => [0, 0], 144 => [0, 0],
            ],
            'arabic' => [
                [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
                [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
                [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
            ],
            'h_sys' => 'p',
            'firdaria' => 'default',
            'bound_type' => 'default',
            'ecliptic' => 0,
            'profection_push_direction' => 0,
            'decanates' => 0,
            'ayanamsa' => 0,
            'location_use' => 0,
        ],
    ];

    protected $noNeedJudgeSummer = ['香港特别行政区', '澳门特别行政区', '台湾省', '北美洲', '大洋洲', '非洲', '南美洲', '欧洲', '亚洲', ''];

    /**
     * 添加档案
     * @throws Exception
     */
    public function add()
    {
        $name = input('name/s', '', 'htmlspecialchars');// 档案名称
        $type = input('type/d');// 档案类型  1男 | 2 女 | 3 男同 | 4 女同 | 5 事件 | 6 卜卦
        $year = input('year/d');// 出生时间-年
        $month = input('month/d');// 出生时间-月
        $day = input('day/d');// 出生时间-日
        $hour = input('hour/d');// 出生时间-时
        $minute = input('minute/d');// 出生时间-分
        $timezone = input('timezone/d', 8);// 出生时间-时区
        $birth_country = input('birth_country/s', '', 'htmlspecialchars');// 出生地点-省
        $birth_province = input('birth_province/s', '', 'htmlspecialchars');// 出生地点-市
        $birth_city = input('birth_city/s', '', 'htmlspecialchars');// 出生地点-区
        $live_country = input('live_country/s', '', 'htmlspecialchars');// 现居地-省
        $live_province = input('live_province/s', '', 'htmlspecialchars');// 现居地-省
        $live_city = input('live_city/s', '', 'htmlspecialchars');// 现居地-省
        $comments = input('comments/s', '', 'htmlspecialchars');// 档案标签如 自己 朋友 案例
        $isself = input('isself/d', 0);// 档案是否为自己 0 否 | 1 是（自己的档案无法删除，无法更改为其他标签）
        $long_deg = input('long_deg/d');// 经度-度
        $long_min = input('long_min/d');// 经度-分
        $ew = input('ew/d');// 东经|西经 1|-1
        $lat_deg = input('lat_deg/d');// 纬度-度
        $lat_min = input('lat_min/d');// 纬度-分
        $ns = input('ns/d');// 南纬北纬  1|-1
        $avatar = input('avatar/s', '', 'htmlspecialchars');// 头像地址
        $referName = input('refer_name/s', '');
        $referLink = input('refer_link/s', '');

        $is_summer = 0;
        $name = str_replace(["\r\n", "\r", "\n"], "", $name);
        // 只判断大陆地区的夏令时
        if (!in_array($birth_country, $this->noNeedJudgeSummer, true))
        {
            $is_summer = isSummerTime($hour, $minute, 0, $month, $day, $year) ? 1 : 0;// 是否开启夏令时
        }

        $birth_longitude = $ew * $long_deg + number_format($long_min / 60, 3);
        $birth_latitude = $ns * $lat_deg + number_format($lat_min / 60, 3);

        $birthDateTime = date('Y-m-d H:i:s', strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute . ':00'));
        $sensorsTrackData = [
            'refer_name' => $referName,
            'refer_link' => $referLink,
            'record_id' => 0,
            'record_name' => $name,
            'record_tag' => $comments,
            'record_sex' => $type === 1 ? '男' : '女',
            'birth_time' => $birthDateTime,
            'is_summer' => $is_summer === 1,
            'birth_country' => $birth_country,
            'birth_province' => $birth_province,
            'birth_city' => $birth_city,
            'birth_longitude' => $birth_longitude,
            'birth_latitude' => $birth_latitude,
            'live_country' => $live_country,
            'live_province' => $live_province,
            'live_city' => $live_city,
            'add_type' => '手动',
            'record_avatar' => $avatar,
            'is_have_avatar' => $avatar !== '',
            'is_success' => true,
            'failed_reson' => '',
            'handle_name' => '新建',// 更新档案方式   修改、新建、更新
        ];

        if (($isself === 1 && $comments !== '自己') || ($comments === '自己' && $isself !== 1))
        {
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = '不满足isself为1且comment为自己';
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), '服务异常，请稍后重试');
        }

        $uid = $this->user['id'];
        $data = [
            'uid' => $uid,
            'name' => $name,
            'type' => $type,
            'year' => $year,
            'month' => $month,
            'day' => $day,
            'hour' => $hour,
            'minute' => $minute,
            'timezone' => $timezone,
            'birth_country' => $birth_country,
            'birth_province' => $birth_province,
            'birth_city' => $birth_city,
            'live_country' => $live_country,
            'live_province' => $live_province,
            'live_city' => $live_city,
            'comments' => $comments,
            'isself' => $isself,
            'long_deg' => $long_deg,
            'long_min' => $long_min,
            'ew' => $ew,
            'lat_deg' => $lat_deg,
            'lat_min' => $lat_min,
            'ns' => $ns,
            'avatar' => $avatar,
            'is_summer' => $is_summer,
        ];
        $validate = validate('Recode');

        if (!$validate->scene('add')->check($data))
        {
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = (string)$validate->getError();
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), (string)$validate->getError());
        }

        $time = time();
        $RecodeCacheModel = new RecodeCacheModel();

        // 查询当前星盘日月水金火木土等星落座落宫存入数据库
        $astro_data = Astrolog::getInstance()->setExecPrefix(config('astrolog.prefix'))
            ->setIsAstrolabe(false)
            ->setRecode1($data)
            ->setUserSetting($this->setting)
            ->getTheRecodeAstro();

        // 仅检测自己的档案，其他人的档案由于其他人看不到，所以不校验
        if ($data['isself'] === 1)
        {
            $res = AliyunFilterWord::checkText($name, 'username');
            //若内容有违规且超过配置的相似比例，则进行隐藏不显示，将标签存入库中
            if ($res)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '昵称涉嫌' . $res['label'] . '，请重新设置';
                SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
                return show(0, '昵称涉嫌' . $res['label'] . '，请重新设置');
            }
        }

        // 查询是否为自己 覆盖已有的记录 20180814
        if ($comments === '自己' && $isself === 1 && $this->isself($uid))
        {
            $recode_old = $RecodeCacheModel->getRecodeLists($this->user['id'], 1);
            if (empty($recode_old))
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '原档案未找到';
                $sensorsTrackData['handle_name'] = '更新';
                SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
                return json(['code' => 10304, 'msg' => 'Recode is not exist.']);
            }
            if (empty($data['avatar']))
            {
                $data['avatar'] = $this->user['avatar'];
            }

            $result = $RecodeCacheModel->UpdateData($uid, $recode_old['id'], $data);

            $data['id'] = $recode_old['id'];// 返回档案id
            $sensorsTrackData['record_id'] = (int)$data['id'];

            if ($result === false)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '档案更新失败';
                $sensorsTrackData['handle_name'] = '更新';
                SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
                return json(['code' => 10305, 'msg' => '档案不存在']);
            }

            //删除用户缓存
            (new User())->updateUserinfo(['id' => $this->user['id']], ['nickname' => $name, 'username' => $name, 'avatar' => $avatar, 'has_self_recode' => 1]);

            Db::table('app_recode_astro')->where(['id' => $recode_old['aid']])->update($astro_data);// 更新档案行星数据

            $sensorsTrackData['is_success'] = true;
            $sensorsTrackData['failed_reson'] = '';
            $sensorsTrackData['handle_name'] = '更新';
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
        } else
        {
            if ($data['comments'] === '自己' && $data['isself'] === 1)
            {
                if ($data['avatar'])
                {
                    $avatar = $data['avatar'];
                } else
                {
                    $avatar = $data['avatar'] = $this->user['avatar'];
                }
            }
//            $rid = Db::table('app_recode')->insertGetId($data);// 返回自增id
            $rid = $RecodeCacheModel->SaveData($uid, $data);
            if (!$rid)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '新建档案失败';
                $sensorsTrackData['handle_name'] = '新建';
                return json(['code' => 0, 'data' => [], 'msg' => '保存失败']);
            }

            if ($data['comments'] === '自己' && $data['isself'] === 1)
            {
                // TODO  【神策打点】用户在APP内首个档案时新建完成添加时触发
                SensorsData::track($this->user['id'], true, 'CompoleteInfo');
                // 新建自己的档案时，更新用户属性
                $userData = [
                    'user_nickname' => $sensorsTrackData['record_name'],// 昵称	STRING	我是一个昵称示例
                    'user_sex' => $sensorsTrackData['record_sex'],// 性别	STRING	男、女
                    'user_birth_time' => $sensorsTrackData['birth_time'],// 出生时间	DATETIME	2021-03-22 11:11:00
                    'user_birth_province' => $sensorsTrackData['birth_country'],// 出生省份	STRING	北京市
                    'user_birth_city' => $sensorsTrackData['birth_province'],// 出生城市	STRING	北京市
                    'user_birth_area' => $sensorsTrackData['birth_city'],// 出生地区	STRING	朝阳区
                    'user_live_province' => $sensorsTrackData['live_country'],// 现居省份	STRING	北京市
                    'user_live_city' => $sensorsTrackData['live_province'],// 现居城市	STRING	北京市
                    'user_live_area' => $sensorsTrackData['live_city'],// 现居地区	STRING	朝阳区
                    'user_is_summer' => $sensorsTrackData['is_summer'],// 是否出生在夏令时	BOOL	true、false
                    'user_birth_longitude' => $sensorsTrackData['birth_longitude'],// 出生地经度	NUMBER	120.56
                    'user_birth_latitude' => $sensorsTrackData['birth_latitude'],// 出生地纬度	NUMBER	35.42
                ];
                SensorsData::profile($this->user['id'], true, $userData, 'set');
                //删除用户缓存
                (new User())->updateUserinfo(['id' => $this->user['id']], ['nickname' => $name, 'username' => $name, 'avatar' => $avatar, 'has_self_recode' => 1]);
            }

            $astro_data['rid'] = $rid;
            $astro_data['create_time'] = $time;

            Db::table('app_recode_info')->insertGetId(['rid' => $rid, 'create_time' => $time, 'last_time' => $time]);// 新增当前档案访问数据

            $aid = Db::table('app_recode_astro')->insertGetId($astro_data);// 新增当前档案行星数据

            $data['id'] = $rid;
            $sensorsTrackData['record_id'] = (int)$rid;
            $sensorsTrackData['is_success'] = true;
            $sensorsTrackData['failed_reson'] = '';
            $sensorsTrackData['handle_name'] = '新建';
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);

            $RecodeCacheModel->UpdateData($uid, $rid, ['aid' => $aid]);
        }
        // 记录注册日志
        Util::logRealTimeAnalyzeWrite(2, [
            'recode_uid' => $data['uid'],
            'recode_rid' => $data['id'],
            'recode_sex' => $data['type'],//档案类型  1男 | 2 女 | 3 男同 | 4 女同 | 5 事件 | 6 卜卦
            'recode_name' => $data['name'],
            'recode_isself' => $data['isself'],
            'recode_year' => $data['year'],
            'recode_month' => $data['month'],
            'recode_day' => $data['day'],
            'recode_hour' => $data['hour'],
            'recode_minute' => $data['minute'],
            'recode_timezone' => $data['timezone'],
            'recode_birth_country' => $data['birth_country'],
            'recode_birth_province' => $data['birth_province'],
            'recode_birth_city' => $data['birth_city'],
            'recode_live_country' => $data['live_country'],
            'recode_live_province' => $data['live_province'],
            'recode_live_city' => $data['live_city'],
            'recode_sun' => explode('-', $astro_data['sun'])[0],
            'recode_ip' => $this->request->ip(),
        ]);

        //返回is_read=1写死【Android需要返回】（0：未读，显示new；1：已读）
        $data['is_read'] = 1;
        $resData = array_merge($data, $astro_data);
        if ($data['isself'] === 1)
        {   // 自己的 档案 记录用户自己的档案ID
            (new HzChatLastSendTimeRecord())->UpdateData($this->user['id'], ['rid' => $data['id']]);
            $hzChatRecordModel = new HzChatRecord();
            $chatId = $hzChatRecordModel->getChatIdByUid($this->user['id']);
            if ($chatId)
            {   // 用户有自己 的会话 且 会话记录没有rid
                $hzChatRecordModel->updateData($chatId, $this->user['id'], ['rid' => $data['id']]);
                // 写入 添加档案对话信息
                (new HzChatRecordDetails())->addRecodeInsertData($this->user['id'], $chatId, $resData);
            }
        }
        return json(['code' => 200, 'data' => $resData, 'msg' => 'ok']);
    }

    /**
     * 编辑档案
     * 名人星案审核通过无法编辑
     * @return mixed
     * @throws Exception
     */
    public function edit()
    {
        $data = [
            'id' => input('id/d'),// 档案id
            'uid' => $this->user['id'],// 用户id
            'name' => input('name/s', '', 'htmlspecialchars'),// 档案名称
            'type' => input('type/d'),// 档案类型  1男 | 2 女 | 3 男同 | 4 女同 | 5 事件 | 6 卜卦
            'year' => input('year/d'),// 出生时间-年
            'month' => input('month/d'),// 出生时间-月
            'day' => input('day/d'),// 出生时间-日
            'hour' => input('hour/d'),// 出生时间-时
            'minute' => input('minute/d'),// 出生时间-分
            'timezone' => input('timezone/d', 8),// 出生时间-时区
            'birth_country' => input('birth_country/s', '', 'htmlspecialchars'),// 出生地点-省
            'birth_province' => input('birth_province/s', '', 'htmlspecialchars'),// 出生地点-市
            'birth_city' => input('birth_city/s', '', 'htmlspecialchars'),// 出生地点-区
            'live_country' => input('live_country/s', '', 'htmlspecialchars'),// 现居地-省
            'live_province' => input('live_province/s', '', 'htmlspecialchars'),// 现居地-省
            'live_city' => input('live_city/s', '', 'htmlspecialchars'),// 现居地-省
            'comments' => input('comments/s', '', 'htmlspecialchars'),// 档案标签如 自己 朋友 案例
            'isself' => input('isself/d', 0),// 档案是否为自己 0 否 | 1 是（自己的档案无法删除，无法更改为其他标签）
            'long_deg' => input('long_deg/d'),// 经度-度
            'long_min' => input('long_min/d'),// 经度-分
            'ew' => input('ew/d'),// 东经|西经 1|-1
            'lat_deg' => input('lat_deg/d'),// 纬度-度
            'lat_min' => input('lat_min/d'),// 纬度-度
            'ns' => input('ns/d'),// 南纬北纬  1|-1
            'avatar' => input('avatar/s', '', 'htmlspecialchars'),// 头像地址
            'status' => 1,// 档案状态
            'from' => 'zhunle',// 档案来源
            'is_summer' => 0, // 默认为不开启夏令时
//            'is_summer' => input('is_summer/d'),// 是否开启夏令时
//            'is_summer' => isSummerTime($hour, $minute, 0, $month, $day, $year) ? 1 : 0,// 是否开启夏令时
        ];
        // 只判断大陆地区的夏令时
        if (!in_array($data['birth_country'], $this->noNeedJudgeSummer, true))
        {
            $data['is_summer'] = isSummerTime($data['hour'], $data['minute'], 0, $data['month'], $data['day'], $data['year']) ? 1 : 0;// 是否开启夏令时
        }

        $birth_longitude = $data['ew'] * $data['long_deg'] + number_format($data['long_min'] / 60, 3);
        $birth_latitude = $data['ns'] * $data['lat_deg'] + number_format($data['lat_min'] / 60, 3);

        $referName = input('refer_name/s', '');
        $referLink = input('refer_link/s', '');

        $birthDateTime = date('Y-m-d H:i:s', strtotime($data['year'] . '-' . $data['month'] . '-' . $data['day'] . ' ' . $data['hour'] . ':' . $data['minute'] . ':00'));
        $sensorsTrackData = [
            'refer_name' => $referName,
            'refer_link' => $referLink,
            'record_id' => (int)$data['id'],
            'record_name' => $data['name'],
            'record_tag' => $data['comments'],
            'record_sex' => $data['type'] === 1 ? '男' : '女',
            'birth_time' => $birthDateTime,
            'is_summer' => $data['is_summer'] === 1,
            'birth_country' => $data['birth_country'],
            'birth_province' => $data['birth_province'],
            'birth_city' => $data['birth_city'],
            'birth_longitude' => $birth_longitude,
            'birth_latitude' => $birth_latitude,
            'live_country' => $data['live_country'],
            'live_province' => $data['live_province'],
            'live_city' => $data['live_city'],
            'add_type' => '手动',
            'record_avatar' => $data['avatar'],
            'is_have_avatar' => $data['avatar'] !== '',
            'is_success' => true,
            'failed_reson' => '',
            'handle_name' => '更新',// 更新档案方式   修改、新建、更新
        ];

        if (($data['isself'] === 1 && $data['comments'] !== '自己') || ($data['comments'] === '自己' && $data['isself'] !== 1))
        {
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = '不满足isself为1且comment为自己';
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), '服务异常，请稍后重试');
        }

        $RecodeCacheModel = new RecodeCacheModel();

        $validate = validate('Recode');

        if (!$validate->scene('edit')->check($data))
        {
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = (string)$validate->getError();
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), (string)$validate->getError());
        }

        $recodeModel = new RecodeCacheModel();
        // 查询未更改前的档案
        $recode_old = $recodeModel->getInfoById($data['id']);

        if (!$recode_old || $recode_old['uid'] != $this->user['id'])
        {
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = '原档案未找到';
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), '档案不存在');
        }

        if ($recode_old['isself'] != 1 && $data['isself'] === 1)
        {
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = '自己的档案只能有一个';
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), '不能添加多个自己的档案');
        }

        // 检测档案编辑是否更改时间
        $timeChange = false;// 默认表示时间未进行更新
        $old_time = strtotime($recode_old['year'] . '-' . $recode_old['month'] . '-' . $recode_old['day'] . ' ' . $recode_old['hour'] . ':' . $recode_old['minute']);
        $new_time = strtotime($data['year'] . '-' . $data['month'] . '-' . $data['day'] . ' ' . $data['hour'] . ':' . $data['minute']);
        // 时间有变动
        if ($old_time != $new_time || $recode_old['timezone'] != $data['timezone'] || $recode_old['is_summer'] != $data['is_summer'])
        {
            $timeChange = true;

            if (Util::getVips($this->user['id'], 0, 0))
            {
                $rec = false;
            } // 检测是否存在档案相关已付款订单
            else
            {
                $rec = RecodeCacheModel::checkAboutOrders(['uid' => $data['uid'], 'id' => $data['id']]);
            }

            // 若有，则档案时间只能为当天内变动，若跨日期，则只能在两小时以内变动
            if ($rec === true)
            {
                // 判断or_day是否存在
                if (empty($recode_old['or_day']) || !$recode_old['or_day'])
                {
                    $recode_old['or_day'] = $recode_old['day'];
                    $data['or_day'] = $recode_old['day'];
                }

                $limit_time = strtotime($recode_old['year'] . '-' . $recode_old['month'] . '-' . $recode_old['or_day'] . ' 12:00');
                $max = $limit_time + 3600 * 14;
                $min = $limit_time - 3600 * 14;

                if ($new_time > $max || $new_time < $min)
                {
                    return show(config('code.error'), '由于该档案购买过付费项目，修改功能受限，改后时间不能与原档案时间差超过两个小时');
                }
            }
        }
        // 检测档案编辑是否更改出生地经纬度
        $old_longitude = ($recode_old['long_deg'] + $recode_old['long_min'] / 60) * $recode_old['ew'];
        $old_latitude = ($recode_old['lat_deg'] + $recode_old['lat_min'] / 60) * $recode_old['ns'];
        $new_longitude = ($data['long_deg'] + $data['long_min'] / 60) * $data['ew'];
        $new_latitude = ($data['lat_deg'] + $data['lat_min'] / 60) * $data['ns'];

        $longLatChange = false;

        if ($old_longitude != $new_longitude || $old_latitude != $new_latitude)
        {
            $longLatChange = true;
        }
        try
        {
            // 查询当前星盘日月水金火木土等星落座落宫存入数据库
            $astro_data = Astrolog::getInstance()->setExecPrefix(config('astrolog.prefix'))
                ->setIsAstrolabe(false)
                ->setRecode1($data)
                ->setUserSetting($this->setting)
                ->getTheRecodeAstro();

            $res = AliyunFilterWord::checkText($data['name'], 'username');
            //若内容有违规且超过配置的相似比例，则进行隐藏不显示，将标签存入库中
            if ($res)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '昵称涉嫌' . $res['label'] . '，请重新设置';
                SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
                return show(0, '昵称涉嫌' . $res['label'] . '，请重新设置');
            }
            $data['sun'] = $astro_data['sun'];
            $data['moon'] = $astro_data['moon'];
            $data['asc'] = $astro_data['asc'];
            $data['merc'] = $astro_data['merc'];
            $data['venu'] = $astro_data['venu'];
            $data['mars'] = $astro_data['mars'];
            $data['jupi'] = $astro_data['jupi'];
            $data['satu'] = $astro_data['satu'];
            $data['non'] = $astro_data['non'];
            $data['lili'] = $astro_data['lili'];
            $data['juno'] = $astro_data['juno'];
            $data['mc'] = $astro_data['mc'];
            // 更新档案数据
            $RecodeCacheModel->UpdateData($this->user['id'], $data['id'], $data);
            // 如果更新的是自己的档案 且 用户修改了档案名称或头像 则更新用户数据 昵称 头像
            if ($recode_old['isself'] == 1
                && ($data['name'] != $recode_old['name'] || $data['avatar'] != $recode_old['avatar']))
            {
                (new User())->updateUserinfo(['id' => $data['uid']], ['nickname' => $data['name'], 'avatar' => $data['avatar']]);
            }
            // 更新档案行星数据
            if ($timeChange || $longLatChange)
            {
                // 记录用户更新档案的时间
                Db::table('app_recode_info')->where('rid', $data['id'])->update(['last_time' => time()]);
                // 更新用户档案档案信息 行星落座信息
                Db::table('app_recode_astro')->where(['id' => $recode_old['aid']])->update($astro_data);
            }
            $data['aid'] = $recode_old['aid'];

            // 档案更新时更新用户档案缓存
            Cache::set('recode_' . $data['id'], $data, 86400 * 7);
            // 档案更新时更新用户档案日月升缓存
            Cache::rm('recode_astro_' . $data['id']);
            //删除首页用户星座缓存
            Cache::rm('d_f_h_sun_in_sign_' . $data['id']);

            // if ($this->user['rid'] == $data['id'])
            // {
            FortuneCache::rmFortuneDayCache($data['id'], strtotime(date('Y-m-d') . ' 12:00:00'));
            // }
        }
        catch (Exception $e)
        {
            Log::write('编辑档案失败：' . $e->getMessage(), 'edit_recode_error', true);
            $sensorsTrackData['is_success'] = false;
            $sensorsTrackData['failed_reson'] = $e->getMessage();
            SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
            return show(config('code.error'), '更新失败');
        }

        //将档案购买的年运订单重新加入队列
//        $this->fortune_redis_job(['rid'=>$data['id'],'uid'=>$data['uid']]);
        $sensorsTrackData['is_success'] = true;
        $sensorsTrackData['failed_reson'] = '';
        SensorsData::track($this->user['id'], true, 'RecordAdd', $sensorsTrackData);
        // 若成功更新自己的档案，则更新用户属性
        if ($data['isself'] === 1)
        {
            $userData = [
                'user_nickname' => $sensorsTrackData['record_name'],// 昵称	STRING	我是一个昵称示例
                'user_sex' => $sensorsTrackData['record_sex'],// 性别	STRING	男、女
                'user_birth_time' => $sensorsTrackData['birth_time'],// 出生时间	DATETIME	2021-03-22 11:11:00
                'user_birth_province' => $sensorsTrackData['birth_country'],// 出生省份	STRING	北京市
                'user_birth_city' => $sensorsTrackData['birth_province'],// 出生城市	STRING	北京市
                'user_birth_area' => $sensorsTrackData['birth_city'],// 出生地区	STRING	朝阳区
                'user_live_province' => $sensorsTrackData['live_country'],// 现居省份	STRING	北京市
                'user_live_city' => $sensorsTrackData['live_province'],// 现居城市	STRING	北京市
                'user_live_area' => $sensorsTrackData['live_city'],// 现居地区	STRING	朝阳区
                'user_is_summer' => $sensorsTrackData['is_summer'],// 是否出生在夏令时	BOOL	true、false
                'user_birth_longitude' => $sensorsTrackData['birth_longitude'],// 出生地经度	NUMBER	120.56
                'user_birth_latitude' => $sensorsTrackData['birth_latitude'],// 出生地纬度	NUMBER	35.42
            ];
            SensorsData::profile($this->user['id'], true, $userData, 'set');
        }

        return show(config('code.success'), '更新成功', array_merge($data, $astro_data));
    }

    /**
     * 删除档案
     * @return mixed
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws Exception
     */
    public function del()
    {
        $id = input('id/d', 0);// 档案id

        $uid = $this->user['id'];

        $validate = validate('Recode');

        if (!$validate->scene('del')->check(['id' => $id, 'uid' => $uid]))
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => '',
                'is_success' => false,
                'failed_reson' => (string)$validate->getError(),
            ]);
            return show(config('code.error'), (string)$validate->getError());
        }
        $recodeModel = new RecodeCacheModel();
        // 查询档案
        $data = $recodeModel->getInfoById($id);

        if (empty($data))
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => '',
                'is_success' => false,
                'failed_reson' => '未找到该档案',
            ]);
            return show(config('code.success'), '档案不存在');
        } elseif ($data['uid'] != $this->user['id'])
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => $data['name'],
                'is_success' => false,
                'failed_reson' => '不能删除属于他人的档案',
            ]);
            return show(config('code.success'), '档案不存在');
        }

        if ($data['isself'] == 1)
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => $data['name'],
                'is_success' => false,
                'failed_reson' => '自己的档案不能删除',
            ]);
            return show(config('code.error'), '自己的档案不能删除');
        }
        // 查询该档案下的笔记 无法删除
        $n_data = Db::table('app_recode_note')->where(['rid' => $id, 'uid' => $uid])->find();

        if (!empty($n_data))
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => $data['name'],
                'is_success' => false,
                'failed_reson' => '存在档案笔记，无法删除',
            ]);
            return show(config('code.error'), '存在档案笔记，无法删除');
        }

        // 检测是否存在档案相关已付款订单
        $rec = $recodeModel::checkAboutOrders(['uid' => $data['uid'], 'id' => $data['id']]);

        if ($rec === true)
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => $data['name'],
                'is_success' => false,
                'failed_reson' => '存在已付款订单，无法删除',
            ]);
            return show(config('code.error'), '存在已付款订单，无法删除');
        }

        // TODO 删除文件 此处无效，需调用 阿里云oss 删除文件
//        if (is_file($data['avatar'])) {
//            if (!is_readable($data['avatar'])) return json(['code' => 10312, 'msg' => 'File can not be changed.']);
//            @unlink($data['avatar']);
//        }
        try
        {
            // 检测档案是否有合盘记录--并给记录做标记
            (new AppSynastryResult())->recodeDel($id, $uid);
            // 删除档案在档案袋中的信息
            Db::table('app_recode_cat')->where('rid', $id)->delete();
            // 删除档案
            $recodeModel->DelData($uid, $id, ['status' => 0]);
//            Db::table('app_recode')->where($map)->update(['status' => 0]);
            // 删除档案缓存
            Cache::rm('recode_' . $id);
            Cache::rm('recode_lists_' . $uid);
        }
        catch (Exception $e)
        {
            SensorsData::track($this->user['id'], true, 'RecordDelete', [
                'record_id' => (int)$id,
                'record_name' => $data['name'],
                'is_success' => false,
                'failed_reson' => $e->getMessage(),
            ]);
            return show(config('code.error'), '删除失败');
        }
        SensorsData::track($this->user['id'], true, 'RecordDelete', [
            'record_id' => (int)$id,
            'record_name' => $data['name'],
            'is_success' => true,
            'failed_reson' => '',
        ]);

        return show(config('code.success'), '删除成功');
    }

    /**
     * 移入档案袋
     * 事物操作
     * @throws Exception
     */
    public function cat()
    {
        $id = (input('id/d', 0));
        $cid = htmlspecialchars(input('cid/s', ''));// 1      1-3-9    1-2     5-11-59-66

        if (!$id)
        {
            return json(['code' => 10315, 'msg' => 'Recode is not exist.']);
        }

        $uid = $this->user['id'];

        $time = time();

        if (strlen($cid) == 1)
        {
            try
            {
                $cat = Db::table('app_cat')->where(['uid' => $uid, 'id' => $cid, 'status' => 0])->findOrFail()->toArray();
            }
            catch (Exception $e)
            {
                $cat = [];
            }

            if (empty($cat))
            {
                return json(['code' => 10317, 'msg' => 'Recode Cat is not exist.']);
            }
            $temp[] = [
                'rid' => $id,
                'cid' => (int)($cid),
                'create_time' => $time,
            ];
        } elseif (strlen($cid) > 1)
        {

            // 当前档案同时移入多个档案袋
            $cat_arr = explode('-', $cid);

            foreach ($cat_arr as $ca)
            {
                $temp[] = [
                    'rid' => $id,
                    'cid' => (int)($ca),
                    'create_time' => $time,
                ];
            }
        }

        $rec = (new RecodeCacheModel())->getInfoById($id);

        if (empty($rec) || $rec['uid'] != $this->user['id'])
        {
            return json(['code' => 10318, 'msg' => 'Recode is not exist.']);
        }
        Db::table('app_recode_cat')->where('rid', $id)->delete();// 先删除
        if (empty($temp))
        {
            return json(['code' => 200, 'msg' => 'Move Success.']);
        }

        model('recodecat')->saveAll($temp);// 后增加

        return json(['code' => 200, 'msg' => 'Move Success.']);
    }

    /**
     * 多档案批量移入单个档案袋
     * @return Json
     * @throws Exception
     * @throws \think\Exception
     * @throws DataNotFoundException
     * @throws DbException
     * @throws PDOException
     */
    public function move_in_cat()
    {
        $id = htmlspecialchars(input('id/s', ''));// 1      1-3-9    1-2     5-11-59-66
        $cid = (input('cid/d', 0));
        $uid = (int)$this->user['id'];

        $time = time();

        // 当前档案同时移入多个档案袋
        $id_arr = explode('-', $id);

        $recodes = (new RecodeCacheModel())->batchGetInfoByIds($id_arr, ['id', 'uid']);
        $temp = [];
        foreach ($recodes as $recodeItem)
        {
            if (!$recodeItem || $recodeItem['uid'] != $uid)
            {
                return json(['code' => 10317, 'msg' => 'Recode is not exist.']);
            }

            $temp[] = [
                'rid' => (int)($recodeItem['id']),
                'cid' => $cid,
                'create_time' => $time,
            ];
        }

        $catData = Db::table('app_cat')->where(['uid' => $uid, 'id' => $cid, 'status' => 0])->field('id')->find();

        if (!$catData)
        {
            return json(['code' => 10316, 'msg' => 'Recode Cat is not exist.']);
        }

        Db::table('app_recode_cat')->where('cid', $cid)->delete();// 先删除

        if (empty($temp))
        {
            return json(['code' => 200, 'msg' => 'Move Success.']);
        }

        model('recodecat')->saveAll($temp);// 后增加

        return json(['code' => 200, 'msg' => 'Move Success.']);
    }

    public function moveout_cat()
    {
        $id = input('id/d', 0);
        $cid = input('cid/d', 0);//1
        if (!$id)
        {
            return json(['code' => 10315, 'msg' => 'Recode is not exist.']);
        }
        if (!trim($cid))
        {
            return json(['code' => 10316, 'msg' => 'Recode Cat is not exist.']);
        }

        $recode = (new \app\common\model\Recode())->getRecode(['id' => $id]);
        if (!$recode || $recode['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '档案不存在');
        }

        try
        {

            Db::table('app_recode_cat')->where(['rid' => $id, 'cid' => $cid])->delete();// 先删除
            return json(['code' => 200, 'msg' => 'Move Success.']);
        }
        catch (\Exception $e)
        {
            return json(['code' => 10316, 'msg' => 'Recode Cat is not exist.']);
        }


    }

    /**
     * 上传头像
     * @return [type] [description]
     */
    public function avatar($dir = 'uploads')
    {
        return (new Avatar())->upload($dir);
    }

    /**
     * 查询用户档案列表
     * @return [type] [description]
     */
    public function lists($id = NULL)
    {
        if ($id === NULL) $id = input('id/d', 0);
        $uid = $this->user['id'];
        if ($id)
        {
            $data = Db::table('app_recode')->alias('r')
                ->join('app_recode_astro ra', 'r.id=ra.rid', 'INNER')
                ->field('r.id,r.name,r.type,r.year,r.month,r.day,r.hour,r.minute,r.timezone,birth_country,birth_province,birth_city,live_country,live_province,live_city,comments,isself,long_deg,long_min,ew,lat_deg,lat_min,ns,avatar,is_summer,uid,aid,sun,moon,merc,venu,mars,jupi,satu,non,lili,juno,asc,mc')
                ->where(['r.id' => $id, 'uid' => $uid])
                ->find();
            if (empty($data))
            {
                return json(['code' => 10322, 'msg' => '档案不存在']);
            }
        } else
        {
            $data = Db::table('app_recode')->alias('r')
                ->join('app_recode_astro ra', 'r.id=ra.rid', 'INNER')
                ->field('r.id,r.name,r.type,r.year,r.month,r.day,r.hour,r.minute,r.timezone,birth_country,birth_province,birth_city,live_country,live_province,live_city,comments,isself,long_deg,long_min,ew,lat_deg,lat_min,ns,avatar,is_summer,uid,aid,sun,moon,merc,venu,mars,jupi,satu,non,lili,juno,asc,mc')
                ->where(['uid' => $uid, 'status' => 1])
                ->select();
        }
        return json(['code' => 200, 'data' => $data, 'msg' => 'ok']);
    }

    /**
     * 查询用户档案列表
     * @return [type] [description]
     */
    public function lists_safe($id = NULL)
    {
        if ($id === NULL) $id = input('id/d');
        $uid = $this->user['id'];

        $field = 'r.id,r.name,r.type,r.year,r.month,r.day,r.hour,r.minute,r.timezone,birth_country,birth_province,birth_city,live_country,live_province,live_city,comments,isself,long_deg,long_min,ew,lat_deg,lat_min,ns,avatar,is_summer,uid,aid,sun,moon,merc,venu,mars,jupi,satu,non,lili,juno,asc,mc';

        if ($id)
        {
            $data = Db::table('app_recode')->alias('r')
                ->join('app_recode_astro ra', 'r.id=ra.rid', 'INNER')
                ->field($field)
                ->where(['r.id' => $id, 'uid' => $uid])
                ->find();
            if (empty($data))
            {
                return json(['code' => 10322, 'msg' => '档案不存在']);
            }
        } else
        {
            $data = Db::table('app_recode')->alias('r')
                ->join('app_recode_astro ra', 'r.id=ra.rid', 'INNER')
                ->field($field)
                ->where(['uid' => $uid, 'status' => 1])
                ->select();
        }
        return json(['code' => 200, 'data' => $data, 'msg' => 'ok']);
    }

    /**
     * 收藏档案
     */
    public function favorite()
    {

    }

    /**
     * 查询是否已有标签为自己的档案
     * @param int $uid
     * @param int $id
     * @return bool
     */
    private function isself($uid = 0, $id = 0)
    {
        if ($uid === NULL || !$uid) return json(['code' => 10323, 'msg' => 'User is not exited.']);

        if ($id === NULL) $data = Db::table('app_recode')->where(['isself' => 1, 'comments' => '自己', 'status' => 1, 'uid' => $uid])->find();

        else $data = Db::table('app_recode')->where(['isself' => 1, 'comments' => '自己', 'uid' => $uid, 'status' => 1, 'id' => ['neq', $id]])->find();

        if (!empty($data)) return true;

        return false;
    }

    /**
     * 查询用户档案列表
     * @return [type] [description]
     */
    public function lists_with_cat()
    {
        $uid = $this->user['id'];

        $data = Db::table('app_cat')->alias('c')
            ->join('app_recode_cat rc', 'c.id=rc.cid', 'INNER')
            ->field('rc.cid,rc.rid')
            ->distinct(true)
            ->where('uid', $uid)
            ->select();

        return json(['code' => 200, 'data' => $data, 'msg' => 'ok']);
    }

}
